Back to all posts

NestJS 설치 및 명령어

NestJS 설치 및 명령어를 정리한 글입니다.

2026년 05월 07일5

개요

NestJS는 Node.js 기반 백엔드 프레임워크이다.

Express처럼 app.get()을 직접 계속 작성하기보다, 요청 처리를 Controller, 로직 처리를 Service, 연결 구성을 Module로 나누어 관리한다.

기본 흐름:

Request
  -> Controller
  -> Service
  -> Response

핵심 파일:

src/main.ts            앱 실행 진입점
src/app.module.ts      모듈 구성
src/app.controller.ts  라우팅 처리
src/app.service.ts     로직 처리

사전 확인

Node.js와 npm 버전 확인:

node -v
npm -v

Node.js가 없으면 Node.js LTS 버전을 먼저 설치한다.

Yarn

설치 확인:

yarn -v

설치:

npm install -g yarn

재확인:

yarn -v

관련 개념:

  • npm은 Node.js 설치 시 같이 들어오는 패키지 매니저
  • yarn은 별도로 설치해서 쓰는 패키지 매니저
  • NestJS 프로젝트 생성 시 사용할 패키지 매니저를 선택할 수 있음

NestJS CLI

설치:

npm install -g @nestjs/cli

설치 확인:

nest --version

프로젝트 생성

새 프로젝트 생성:

nest new nest-basic

패키지 매니저 선택 화면에서 yarn 선택.

이동:

cd nest-basic

실행

개발 서버 실행:

yarn start:dev

기본 주소:

http://localhost:3000

확인:

curl http://localhost:3000

기본 응답 예시:

Hello World!

실행 명령어

yarn start       # 일반 실행
yarn start:dev   # 개발 모드 실행, 파일 변경 감지
yarn build       # 빌드
yarn test        # 테스트 실행

기본 파일 구조

src/main.ts
src/app.module.ts
src/app.controller.ts
src/app.service.ts

main.ts

NestJS 애플리케이션을 생성하고 서버를 실행하는 진입점.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

역할:

  • NestFactory.create(AppModule): 루트 모듈을 기준으로 앱 생성
  • app.listen(3000): 3000번 포트에서 서버 실행

app.module.ts

Controller와 Service를 NestJS 앱에 등록하는 파일.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

구성:

  • imports: 다른 모듈 연결
  • controllers: 요청을 받는 Controller 등록
  • providers: 주입 가능한 Service 등록

app.controller.ts

요청 URL과 HTTP 메서드를 처리하는 파일.

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHome() {
    return this.appService.getHome();
  }

  @Get('post')
  getPost() {
    return this.appService.getPost();
  }

  @Get('user')
  getUser() {
    return this.appService.getUser();
  }
}

라우팅:

GET /      -> getHome()
GET /post  -> getPost()
GET /user  -> getUser()

app.service.ts

Controller에서 호출하는 실제 처리 로직을 작성하는 파일.

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHome() {
    return 'Home Page';
  }

  getPost() {
    return 'Post Page';
  }

  getUser() {
    return 'User Page';
  }
}

@Injectable()이 붙은 클래스는 NestJS의 의존성 주입 대상으로 사용할 수 있다.

Express와 비교

const express = require('express');

const app = express();

app.get('/', (req, res) => res.send('Hello, World!'));
app.get('/post', (req, res) => res.send('<h1>Post Page</h1>'));
app.get('/user', (req, res) => res.send('<h1>User Page</h1>'));

app.use((req, res) => {
  res.status(404).send('<h1>Page not found</h1>');
});

app.listen(3000, () => {
  console.log('server on localhost:3000');
});

NestJS 대응:

app.get('/', ...)       -> @Get()
app.get('/post', ...)   -> @Get('post')
app.get('/user', ...)   -> @Get('user')
app.listen(3000)        -> app.listen(3000) in main.ts

라우팅 규칙

기본 경로

@Controller()
export class AppController {
  @Get()
  getHome() {
    return 'Home Page';
  }
}
GET /

하위 경로

@Controller()
export class AppController {
  @Get('post')
  getPost() {
    return 'Post Page';
  }
}
GET /post

Controller prefix

@Controller('posts')
export class PostsController {
  @Get()
  findAll() {
    return 'Post List';
  }

  @Get('recent')
  findRecent() {
    return 'Recent Posts';
  }
}
GET /posts
GET /posts/recent

기초 동작 예제

목표 라우팅:

GET /      -> Home Page
GET /post  -> Post Page
GET /user  -> User Page

src/app.controller.ts

import { Controller, Get } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  getHome() {
    return 'Home Page';
  }

  @Get('post')
  getPost() {
    return 'Post Page';
  }

  @Get('user')
  getUser() {
    return 'User Page';
  }
}

동작 확인:

curl http://localhost:3000
curl http://localhost:3000/post
curl http://localhost:3000/user

예상 응답:

Home Page
Post Page
User Page

주의점

@Get() 중복

잘못된 예:

@Get()
getHome() {
  return 'Home Page';
}

@Get()
getPost() {
  return 'Post Page';
}

둘 다 같은 GET / 경로로 등록된다.

수정:

@Get()
getHome() {
  return 'Home Page';
}

@Get('post')
getPost() {
  return 'Post Page';
}

응답 방식

NestJS 기본 방식:

@Get()
getHome() {
  return 'Home Page';
}

Express 방식:

app.get('/', (req, res) => {
  res.send('Home Page');
});

NestJS에서는 특별한 경우가 아니면 res.send()보다 return을 사용한다.

명령어 모음

npm install -g yarn
npm install -g @nestjs/cli
nest --version
nest new nest-basic
cd nest-basic
yarn start:dev

Controller 생성:

nest generate controller posts

Service 생성:

nest generate service posts

축약 명령어:

nest g controller posts
nest g service posts

문제 해결

nest: command not found

확인:

nest --version

재설치:

npm install -g @nestjs/cli

yarn: command not found

재설치:

npm install -g yarn

3000번 포트 충돌

src/main.ts

await app.listen(3001);

접속 주소:

http://localhost:3001

수정 사항이 반영되지 않음

개발 모드 실행 여부 확인:

yarn start:dev

관련 개념

  • [[📗 Node.js 를 활용한 서버 기초1]]
  • [[📗 Node.js 를 활용한 서버 기초2]]
  • [[📗 Node.js 를 활용한 서버 기초3 (express)]]

키워드

NestJS
Controller
Service
Module
Provider
Decorator
Dependency Injection